﻿using HLStock.Common;
using HLStock.DBAccess;
using HLStock.WmsApi;
using HLStock.WmsService;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using System.Reflection;
using HLStock.WmsApi;
using Microsoft.AspNetCore.Authorization.Policy;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using HLStock.WmsApi.AuthenticationInjection;
using HLStock.Model;

namespace HLStock
{
    public static class Starter
    {
        public static void PreSetup(WebApplicationBuilder builder)
        {
            RuntimeVariable.ROOT_PATH = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            builder.Services.AddHttpContextAccessor();
            builder.Services.AddScoped<DbInstance>();
            builder.Services.AddScoped<OnlineUser>();
            builder.Services.AddMvc(o =>
            {
                o.ValueProviderFactories.Add(new JQueryQueryStringValueProviderFactory());
                o.Filters.Add(typeof(GlobalExceptions));
                o.Filters.Add(typeof(MyTokenGlobalExceptions));
                o.Filters.Add(typeof(MyGlobalExceptions));
            }).AddNewtonsoftJson(options => {
                options.SerializerSettings.Converters.Add(new MyBooleanJsonConveter());
                options.SerializerSettings.Converters.Add(new MyDateTimeJsonConveter());
                options.SerializerSettings.ContractResolver = new MyDefaultContractResolver();
            });
            SetupAuthorization(builder);
        }
        private static void SetupAuthorization(WebApplicationBuilder builder)
        {
            builder.Services.AddAuthentication(option =>
            {
                option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                option.DefaultForbidScheme = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(option =>
            {
                option.TokenValidationParameters = TokenManager.GetTokenValidationParameters();
            });
            builder.Services.AddAuthorization(authorizationOptions =>
            {
                authorizationOptions.AddPolicy(Const.BASE_RULE, policy => policy.AddRequirements(new MyAuthorizationRequirement()));
            });
            builder.Services.AddScoped<IMyFailureReason, MyFailureReason>();
            builder.Services.AddScoped<IAuthorizationHandler, MyAuthorizationHandler>();
            builder.Services.AddScoped<IAuthorizationMiddlewareResultHandler, MyAuthorizationMiddlewareResultHandler>();
        }
        public static void Setup(WebApplication app)
        {
            RuntimeVariable.GLOBAL_CONFIG = app.Configuration;
            ServiceLoader.InitInstance(app.Services);
            RuntimeVariable.IS_DEVELOP = app.Environment.IsDevelopment();
            InitSystemMod();
        }

        static void InitSystemMod()
        {
            using (DbInstance dbInstance = new DbInstance())
            {
                DbQuery<ModModel> modQry = new DbQuery<ModModel>(dbInstance);
                SystemVar.ModuleList = modQry.ToList();
            }
        }
        public static void AddScopeds(IServiceCollection service)
        {
            var sdProviders = typeof(BaseServiceProvider<>).Assembly.GetExportedTypes().Where(r =>
                r.BaseType != null
                && r.BaseType.IsGenericType
                && r.BaseType.GetGenericTypeDefinition() == (typeof(BaseServiceProvider<>))
                && !r.IsAbstract);
            foreach (var provider in sdProviders)
            {
                service.AddScoped(provider);
            }
        }
    }
}
